﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using System.Web;
using TweetSharp;

namespace tww
{
    public class TwitterHelper
    {
        #region Fields
        OAuthHelper hlp;
        Dictionary<int, long> _allFollowers;
        Dictionary<int, long> _allFriends;
        static TwitterHelper instance;
        String ConsumerKey = ConfigurationManager.AppSettings["consumer_key"];
        string ConsumerSecret = ConfigurationManager.AppSettings["consumer_secret"];
        #endregion

        #region Props
        public string TokenKey { get; set; }
        public string SecretKey { get; set; }
        public Dictionary<int, long> AllFollowers { get { return _allFollowers; } }
        public Dictionary<int, long> AllFriends { get { return _allFriends; } }
        #endregion

        #region Ctor
        private TwitterHelper()
        {
            hlp = new OAuthHelper();
            _allFollowers = new Dictionary<int, long>();
            _allFriends = new Dictionary<int, long>();
        }
        public static TwitterHelper Get
        {
            get
            {
                if (instance == null)
                    instance = new TwitterHelper();
                return instance;
            }
        }
        #endregion

        #region Public Methods

        public List<TwitterObject> SearchUser(string user)
        {
            return hlp.SearchUser(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, user);

            //List<TwitterObject> users = new List<TwitterObject>();
            //TwitterService twitterService = new TwitterService(ConsumerKey, ConsumerSecret);
            //twitterService.AuthenticateWith(TokenKey, SecretKey);
            //var options = new SearchForUserOptions { Count = 100, Q = user };

            //var tweets = twitterService.SearchForUser(options);
            //foreach (var tweet in tweets)
            //{
            //    users.Add(new TwitterObject { Adi = tweet.ScreenName, ID = tweet.Id, TwitterAdi = tweet.ScreenName });
            //}
            //return users;
        }

        public List<TwitterObject> getFollowers(Int64 userID, string name)
        {
            var obj = hlp.getFollowersID(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, name, -1, 200);
            return hlp.getUserLookup(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, obj.ids.Take(100).ToArray());


            //List<TwitterObject> users = new List<TwitterObject>();
            //TwitterService twitterService = new TwitterService(ConsumerKey, ConsumerSecret);
            //twitterService.AuthenticateWith(TokenKey, SecretKey);
            //ListFollowersOptions op = new ListFollowersOptions() { ScreenName = name };


            //TweetSharp.TwitterCursorList<TwitterUser> followers = twitterService.ListFollowers(op);
            //while (followers.NextCursor > 0)
            //{
            //    foreach (var item in followers)
            //    {
            //        users.Add(new TwitterObject() { Adi = item.Name, ID = item.Id, TwitterAdi = item.ScreenName });
            //    }

            //    //Thread.Sleep(5000);

            //    op.Cursor = followers.NextCursor;
            //    followers = twitterService.ListFollowers(op);
            //    if (followers == null)
            //    {
            //        break;
            //    }

            //}

            //foreach (long item in allIDs)
            //{
            //    try
            //    {
            //        var user = twitterService.GetUserProfileFor(new GetUserProfileForOptions() { UserId = item });
            //        if (user != null)
            //        {
            //            users.Add(new TwitterObject() { Adi = user.Name, ID = user.Id, TwitterAdi = user.ScreenName });
            //        }
            //    }
            //    catch (Exception)
            //    {
            //    }
            //}

            //return users;
        }

        public List<TwitterObject> getFriends(string name)
        {
            //var obj = hlp.getFriendsID(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, name, -1);
            return hlp.getFriends(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, name);

            //List<TwitterObject> users = new List<TwitterObject>();
            //TwitterService twitterService = new TwitterService(ConsumerKey, ConsumerSecret);
            //twitterService.AuthenticateWith(TokenKey, SecretKey);
            //var op = new ListFriendIdsOfOptions() { Count = 100, UserId = userID, ScreenName = name };

            //TweetSharp.TwitterCursorList<long> twitterUser = twitterService.ListFriendIdsOf(op);

            //foreach (long item in twitterUser)
            //{
            //    try
            //    {
            //        var user = twitterService.GetUserProfileFor(new GetUserProfileForOptions() { UserId = item });
            //        if (user != null)
            //        {
            //            users.Add(new TwitterObject() { Adi = user.Name, ID = user.Id, TwitterAdi = user.ScreenName });
            //        }
            //    }
            //    catch (Exception)
            //    {
            //    }
            //}

            //return users;
        }

        public void FollowUser(params Int64[] users)
        {
            foreach (Int64 item in users)
            {
                hlp.FollowUser(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, item, true);
            }
        }

        public void unFollowUser(params Int64[] users)
        {
            foreach (Int64 item in users)
            {
                hlp.FollowUser(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, item, false);
            }
        }

        public void loadFollower(string name)
        {
            long cursor = -1;
            while (true)
            {
                long cr = loadFollower(name, cursor);
                if (cr == 0)
                {
                    break;
                }
                else
                {
                    cursor = cr;
                }
            }
        }

        public void loadFriends(string name)
        {
            long cursor = -1;
            while (true)
            {
                long cr = loadFriends(name, cursor);
                if (cr == 0)
                {
                    break;
                }
                else
                {
                    cursor = cr;
                }
            }
        }

        public List<TwitterObject> nextFollower(string name, int start)
        {
            long[] ids = AllFollowers.Where(x => x.Key > start).Take(200).Select(x => x.Value).ToArray();
            if (ids.Length > 0)
                return hlp.getUserLookup(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, ids);
            return new List<TwitterObject>();
        }

        public List<TwitterObject> BeniTakipEtmeyenleriTakipEtme(Int64 userID, string name)
        {
            List<TwitterObject> sonuc = new List<TwitterObject>();
            Queue<long> havuz = new Queue<long>();
            Array.ForEach((from u in AllFriends.Values
                           where !AllFollowers.Values.Contains(u)
                           select u).ToArray(), havuz.Enqueue);

            List<long> array = new List<long>();
            while (true)
            {
                if (havuz.Count == 0)
                    break;

                if (havuz.Count > 100)
                {
                    for (int i = 0; i < 100; i++)
                    {
                        array.Add(havuz.Dequeue());
                    }

                    sonuc.AddRange(hlp.getUserLookup(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, array.ToArray()));
                    array.Clear();
                }
                else
                {
                    array.Add(havuz.Dequeue());
                }
            }

            if (array.Count > 0)
            {
                sonuc.AddRange(hlp.getUserLookup(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, array.ToArray()));
            }

            return sonuc;
        }

        public List<Tweet> KelimeAra(Int64 userID, string name, string keyword)
        {
            OAuthHelper hlp = new OAuthHelper();
            return hlp.SearchTweets(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, keyword);
        }

        public List<TwitterObject> BelliBirTarihtenSonraTweetAtmayanlar(Int64 userID, string name, int gun)
        {
            List<TwitterObject> sonuc = new List<TwitterObject>();
            if (AllFriends.Count == 0)
                loadFriends(name);

            int last = 0;
            while (true)
            {
                long[] fr = AllFriends.Where(x => x.Key > last).Select(x => x.Value).Take(100).ToArray();
                if (fr.Length == 0)
                {
                    break;
                }
                else
                {
                    last = fr.Length;

                    var friends = hlp.getUserLookup(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, fr);
                    sonuc.AddRange(friends.Where(x => x.status.Tarih < DateTime.Now.Date.AddDays((-1) * gun)));
                }
            }
            return sonuc;
        }

        #endregion

        #region Private Methods

        private long loadFollower(string name, long next)
        {
            var obj = hlp.getFollowersID(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, name, next, 5000);
            if (obj != null)
            {
                int max = 0;
                if (AllFollowers.Count > 0)
                    max = AllFollowers.Select(x => x.Key).Max();

                foreach (long item in obj.ids)
                {
                    max++;
                    AllFollowers.Add(max, item);
                }
                return obj.next_cursor;
            }
            return 0;
        }

        private long loadFriends(string name, long next)
        {
            var obj = hlp.getFriendsID(TokenKey, SecretKey, ConsumerKey, ConsumerSecret, name, next, 5000);
            if (obj != null)
            {
                int max = 0;
                if (AllFriends.Count > 0)
                    max = AllFriends.Select(x => x.Key).Max();

                foreach (long item in obj.ids)
                {
                    max++;
                    AllFriends.Add(max, item);
                }
                return obj.next_cursor;
            }
            return 0;
        }

        #endregion

    }
}